package juc.blockqueue.delayqueue;

/**
 * @ClassName ConnectionPool
 * @PackageName juc.blockqueue.delayqueue
 * @projectName myThread
 * @Description TODO
 * @Author games
 * @Date 2025/9/4 下午1:32
 * @Version 1.0
 */
import java.util.concurrent.*;

/**
 * PooledConnection类实现了Delayed接口，表示一个可延迟的连接对象
 * 用于连接池管理，支持超时检测和自动关闭
 */
class PooledConnection implements Delayed {
    private final String connectionId;    // 连接ID标识
    private final long timeoutTime;       // 超时时间戳
    private boolean inUse = false;        // 连接是否在使用中

    /**
     * 构造函数，初始化连接对象并设置超时时间
     * @param connectionId 连接唯一标识
     * @param timeoutMillis 超时时间（毫秒）
     */
    public PooledConnection(String connectionId, long timeoutMillis) {
        this.connectionId = connectionId;
        this.timeoutTime = System.currentTimeMillis() + timeoutMillis;
    }

    /**
     * 获取剩余延迟时间
     * @param unit 时间单位
     * @return 剩余延迟时间
     */
    @Override
    public long getDelay(TimeUnit unit) {
        long diff = timeoutTime - System.currentTimeMillis();
        return unit.convert(diff, TimeUnit.MILLISECONDS);
    }

    /**
     * 比较两个Delayed对象的延迟时间
     * @param other 另一个Delayed对象
     * @return 比较结果
     */
    @Override
    public int compareTo(Delayed other) {
        return Long.compare(this.timeoutTime, ((PooledConnection) other).timeoutTime);
    }

    // Getter和Setter方法
    public String getConnectionId() { return connectionId; }
    public boolean isInUse() { return inUse; }
    public void setInUse(boolean inUse) { this.inUse = inUse; }

    /**
     * 关闭连接
     */
    public void close() {
        System.out.println("Closing connection: " + connectionId);
    }
}

/**
 * ConnectionPool类实现了基于DelayQueue的连接池
 * 支持连接的超时管理和自动清理
 */
public class ConnectionPool {
    private final DelayQueue<PooledConnection> timeoutQueue = new DelayQueue<>();  // 延迟队列，用于管理连接超时

    /**
     * 添加新连接到连接池
     * @param id 连接ID
     * @param timeoutMillis 超时时间（毫秒）
     */
    public void addConnection(String id, long timeoutMillis) {
        PooledConnection conn = new PooledConnection(id, timeoutMillis);
        timeoutQueue.put(conn);
        System.out.println("Added connection: " + id);
    }

    /**
     * 启动超时检查线程
     * 定期检查并关闭超时的未使用连接
     */
    public void startTimeoutChecker() {
        new Thread(() -> {
            try {
                while (true) {
                    // 从队列中获取超时的连接
                    PooledConnection timedOutConn = timeoutQueue.take();
                    // 只有未使用的连接才会被关闭
                    if (!timedOutConn.isInUse()) {
                        timedOutConn.close();
                        System.out.println("Connection timed out: " + timedOutConn.getConnectionId());
                    }
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
    }

    /**
     * 主函数，演示连接池的使用
     * @param args 命令行参数
     * @throws InterruptedException 线程中断异常
     */
    public static void main(String[] args) throws InterruptedException {
        ConnectionPool pool = new ConnectionPool();
        pool.startTimeoutChecker();  // 启动超时检查线程

        // 添加两个测试连接，分别设置不同的超时时间
        pool.addConnection("conn1", 1000); // 1秒后超时
        pool.addConnection("conn2", 2000); // 2秒后超时

        Thread.sleep(3000); // 等待连接超时
    }
}
